/**********************************************************************************************/
// syntez.cpp
//
// source file for implementation of synthez of the Mili automat
// Copyright Diamant Group 2008
/**********************************************************************************************/

#include "syntez.h"
#include "dgtKernel.h"
#include "dgt_Algorithm.h"
#include "dgt_AlgLogic.h"
#include "dgt_Utils.h"

/**********************************************************************************************/
int	get_TriggerCount( dgt_Algorithm_Ptr inAlg )
{
	int maxBlock = 0;

	dgt_AlgLogArray tArray = inAlg->get_Logics();
	for( unsigned i = 0; i < tArray.Count(); i++ )
	{
		dgt_AlgLogic_Ptr tLog = tArray.Item( i );
		int stBlock = tLog->get_StartBlock();
		int endBlock = tLog->get_FinBlock();

		if( stBlock > maxBlock )
			maxBlock = stBlock;
		if( endBlock > maxBlock )
			maxBlock = endBlock;
	}

	return ceil( log( (double) maxBlock ) / log( (double) 2 ) );
}

/**********************************************************************************************/
dgt_LogTableArray get_LogTablesTriggers( dgt_Algorithm_Ptr inAlg, dgt_Element_Ptr inTrig )
{
	dgt_AlgLogArray tLogArray = inAlg->get_Logics();
	dgt_LogTableArray result;

	unsigned TrigCount = get_TriggerCount( inAlg );
	unsigned CondCount = inAlg->get_ConditionsCount();

	wxArrayString VarNames;
	for( unsigned i = 0; i < TrigCount; i++ )
	{
		wxString str;
		str.Format( _("S%d"), i );
		VarNames.Add( str );
	}
	for( unsigned i = 0; i < CondCount; i++ )
	{
		wxString str;
		str.Format( _("X%d"), i );
		VarNames.Add( str );
	}
	
	for( unsigned i = 0; i < TrigCount; i++ )
	{
		for( unsigned j = 0; j < inTrig->get_ICount(); j++ )
		{
			dgt_LogicTable_Ptr tLog( new dgt_LogicTable( VarNames ) );

			for( unsigned k = 0; k < pow( (double) 2, (double) ( TrigCount + CondCount )); k++ )
				tLog->set_Value( k, false );

			for( unsigned k = 0; k < tLogArray.Count(); k++ )
			{
				dgt_AlgLogic_Ptr tAlgLog = tLogArray.Item( k );
				
				bool stBit = get_Bit( tAlgLog->get_StartBlock(), i );
				bool endBit = get_Bit( tAlgLog->get_FinBlock(), i );

				wxArrayShort tSyg = inTrig->get_InpSygnals( stBit, endBit );

				// 1
				if( tSyg.Item( j ) )
				{
					wxArrayInt tConditions = tAlgLog->get_CondList();

					wxBoolArray tBools;
					for( unsigned l = 0; l < TrigCount; l++ )
						tBools.Add( get_Bit( tAlgLog->get_StartBlock(), l ) );
					for( unsigned l = 1; l <= CondCount; l++ )
					{
						bool isCond = false;

						for( unsigned m = 0; m < tConditions.Count(); m++ )
							if( tConditions.Item( m ) == l )
								isCond = true;
						tBools.Add( isCond );
					} 
					
					tLog->set_Value( get_NumFromBits( tBools ), true );
				}
			}
			result.Add( tLog );
		}
	}
	return result;
}
